#!/usr/bin/python3
"""
This script generates 3 6-digit TOTP-sequences, which were valid during the
first 30 seconds of the current hour. From the 3 sequences 6 portnumbers are
generated in the high port ranges (32768-65535).

This script is to be used on both server (in /root/bin/) and on client (in
~/bin/).

To generate values for KEY1, KEY2 and KEY3 below, install pyotp and run this
command three times:
    python3 -c 'import pyotp ; print(pyotp.random_base32())'

After filling in the values below, pyotp can be uninstalled again.  This script
uses a low level algorithm deliberately: once the keys are there, this script
depends on the standard python libraries only.
"""

import base64
import hashlib
import hmac
import struct
import time

KEY1 = ''
KEY2 = ''
KEY3 = ''
BASES = [33000, 34000, 35000, 36000, 37000, 38000]


parts = []

for key in (KEY1, KEY2, KEY3):
    decoded_key = base64.b32decode(key, True)
    (tm_year, tm_mon, tm_mday, tm_hour, _, _, _, _, _) = time.localtime()
    tme = time.mktime((tm_year, tm_mon, tm_mday, tm_hour, 0, 0, 0, 0, 0))
    msg = struct.pack(">Q", int(tme)//30)
    h = hmac.new(decoded_key, msg, hashlib.sha1).digest()
    o = o = h[19] & 15
    hotp = str((struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000)
    prefix = (6-len(hotp)) * '0'
    totp = prefix + hotp
    parts.append(int(totp[:3]))
    parts.append(int(totp[3:]))

ports = [str(sum(pair)) for pair in zip(BASES, parts)]
print(" ".join(ports))
